#!/usr/bin/env python3
"""Generate C# ResourceUtilities partial class with embedded JS resources.

Usage:
  generate_resources_tool.py --output path/to/ResourceUtilities.g.cs \
      --input Ident1=path/to/file1.js \
      --input Ident2=path/to/file2.js ...

Each identifier becomes a const string in ResourceUtilities class.
The content is emitted as a C# raw string literal using 5-quotes.

TODO:
It would be nice to convert this small single-file utility to .NET10/C#,
so it would work like `dotnet run generate_resources.cs -- <args>`.
Meaning .NET developers can easily support it.
"""

import argparse
import os
import sys
from typing import List, Tuple


def parse_args(argv: List[str]) -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument("--output", required=True)
    parser.add_argument("--input", action="append", default=[], help="IDENT=path")
    return parser.parse_args(argv)


def parse_input_spec(spec: str) -> Tuple[str, str]:
    if "=" not in spec:
        raise ValueError(f"Invalid --input value, expected IDENT=path, got: {spec}")
    ident, path = spec.split("=", 1)
    ident = ident.strip()
    path = path.strip()
    if not ident:
        raise ValueError(f"Empty identifier in --input value: {spec}")
    if not path:
        raise ValueError(f"Empty path in --input value: {spec}")
    return ident, path


def generate(output: str, inputs: List[Tuple[str, str]]) -> None:
    props: List[str] = []
    for prop_name, path in inputs:
        with open(path, "r", encoding="utf-8") as f:
            content = f.read()
        # Use a C# raw string literal with five quotes. For a valid raw
        # literal, the content must start on a new line and the closing
        # quotes must be on their own line as well. We assume the content
        # does not contain a sequence of five consecutive double quotes.
        #
        # Resulting C# will look like:
        #   """""
        #   <content>
        #   """""
        literal = '"""""\n' + content + '\n"""""'
        props.append(f"    internal const string {prop_name} = {literal};")

    lines: List[str] = []
    lines.append("// <auto-generated />")
    lines.append("namespace OpenQA.Selenium.Internal;")
    lines.append("")
    lines.append("internal static partial class ResourceUtilities")
    lines.append("{")
    for p in props:
        lines.append(p)
    lines.append("}")
    lines.append("")

    os.makedirs(os.path.dirname(output), exist_ok=True)
    with open(output, "w", encoding="utf-8", newline="\n") as f:
        f.write("\n".join(lines))


def main(argv: List[str]) -> int:
    args = parse_args(argv)
    inputs: List[Tuple[str, str]] = []
    for spec in args.input:
        ident, path = parse_input_spec(spec)
        inputs.append((ident, path))
    generate(args.output, inputs)
    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv[1:]))
